/*
 *-----------------------------------------------------------------
 *	 voronoi.c
 *-----------------------------------------------------------------
 */

/*
 *-----------------------------------------------------------------
 *	 INCLUDE
 *-----------------------------------------------------------------
 */
#include <stdio.h>
#include <stdlib.h>
#include "common.h"

/*
 *--------------------------------------------------------------------
 * 	EXTERN GLOBAL VARIABLES
 *--------------------------------------------------------------------
 */
extern CELL 	*headC; /* declared in list.c */
extern CELL 	*zedC;  /* declared in list.c */

extern voronoiType *myVoronoiList;	/* declared in main.c */
extern faceType *myFacesList;
extern float min_x,min_y,max_x,max_y;
extern int numberOfVoronoiVert;

/*
 *--------------------------------------------------------------------
 *--------------------------------------------------------------------
 */
void computeVoronoi(void)
{
	
/* Marcelo remember. Depending if I was in graphics mode
   I'd artificially insert points far away from the border
   so that the final voronoi would look "better". This is
   giving me problems to save the image as a postscript file
   when I'm in interactive mode and therefore I'm removing
   that feature. If I want it back I just have to uncommment
   the parts below with the #ifdef */

  add_points_at_infinity();
  add_cells_at_border();

  /* call the voronoi part */
  getVoronoi(headC,zedC,&myVoronoiList,&myFacesList, &numberOfVoronoiVert);

  printf("\nNumber of vertices in the Voronoi diagram: %d\n",
	 numberOfVoronoiVert);

  /* after the Voronoi is computed, remove the cells
     at infinity from the global list */

  remove_points_at_infinity();
  remove_cells_at_border();
}

/*
 *------------------------------------------------------------------------
 *------------------------------------------------------------------------
 */
void freeVoronoiSpace(void)
{
  free(myVoronoiList);
  free(myFacesList);
}


/*
 *--------------------------------------------------------------
 *--------------------------------------------------------------
 */
void add_cells_at_border(void)
{
  int i,j;
  float nmin_x,nmin_y,nmax_x,nmax_y,range_x,range_y;
  float rx,ry;

  nmin_x = min_x - 10.0;
  nmin_y = min_y - 10.0;
  nmax_x = max_x + 10.0;
  nmax_y = max_y + 10.0;
  range_x = nmax_x - nmin_x;
  range_y = nmax_y - nmin_y;
  
  for(i=0; i<20; i++){
    rx = fran(-max_x*0.01,max_x*0.01);
    create_cell(nmin_x+rx,range_y+(i*nmin_y),0.0,0,0,TRUE);
    create_cell(nmax_x+rx,range_y+(i*nmin_y),0.0,0,0,TRUE);
  }
  for(i=0; i<20; i++){
    ry = fran(-max_y*0.01,max_y*0.01);
    create_cell(range_x+(i*nmin_x),nmin_y+ry,0.0,0,0,TRUE);
    create_cell(range_x+(i*nmin_x),nmax_y+ry,0.0,0,0,TRUE);
  }
}


/*
 *--------------------------------------------------------------
 *--------------------------------------------------------------
 */
void remove_cells_at_border(void)
{
  CELL *s,*to_remove;

  to_remove = headC->next;
  while(to_remove != zedC){
    while(to_remove->border != TRUE) to_remove = to_remove->next;
    s = to_remove->next;
    remove_list(to_remove,headC);
    to_remove = s;
  }
}

/*
 *--------------------------------------------------------------
 *--------------------------------------------------------------
 */
void remove_points_at_infinity(void)
{
  CELL *s,*to_remove;
  int i;

  to_remove = headC->next;
  while(to_remove->x != -1*max_x*FACTOR) to_remove = to_remove->next;
  for(i=0;i<4;i++){
    s = to_remove->next;
    remove_list(to_remove,headC);
    to_remove = s;
  }
}

/*
 *--------------------------------------------------------------
 *--------------------------------------------------------------
 */
void add_points_at_infinity(void)
{
  create_cell(-1*max_x*FACTOR,-1*max_y*FACTOR,0.0,0,0,TRUE);
  create_cell(2*max_x*FACTOR,-1*max_y*FACTOR,0.0,0,0,TRUE);
  create_cell(-1*max_x*FACTOR,2*max_y*FACTOR,0.0,0,0,TRUE);
  create_cell(2*max_x*FACTOR,2*max_y*FACTOR,0.0,0,0,TRUE);
	
}

/*
 *------------------------------------------------------------------------
 *------------------------------------------------------------------------
 */
void print_voronoi_faces_list(int np)
{
  int i,j,k,number_of_vert;
  CELL *s;

  for(i=0;i<np;i++){
    number_of_vert = myFacesList[i].faceSize;
    s = myFacesList[i].site;
    printf("Face = %d with %d vertices for cell(%3.2f,%3.2f)\n",
	   i,number_of_vert,s->x,s->y);
    for(j=0;j<number_of_vert;j++){
      k = myFacesList[i].vorPts[j];
      printf("x = %f y = %f\n",myVoronoiList[k].x,myVoronoiList[k].y);
    }
  }
}
